package com.happyelements.display
{
	import flash.display.BitmapData;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	/**
	 *
	 * @author Steven
	 *
	 */
	public class HEDisplayObjectContainer extends HEDisplayObject
	{
		private var _children:Vector.<HEDisplayObject> = new Vector.<HEDisplayObject>();
		
		override public final function update(canvas:BitmapData, rect:Rectangle):void
		{
			super.update(canvas, rect);
			
			for (var i:int = 0; i < _children.length; i++)
			{
//				常规剔除效率反不如完整渲染    屏幕外剔除有场景处理，不放在显示列表中
//				var childRect:Rectangle = _children[i].getRect();
//				var offsetPoint:Point = _children[i].localToGlobal(childRect.topLeft);
//				childRect.x = offsetPoint.x;
//				childRect.y = offsetPoint.y;
//				
//				if (childRect.intersects(rect) || childRect.width == 0 && childRect.height == 0)		//未加载资源的宽高属性都为0
//				{
//					_children[i].update(canvas, rect);
//				}
				
				_children[i].update(canvas, rect);
			}
		}
		
		override public final function get width():Number
		{
			return getRect(this).width;
		}
		
		override public final function get height():Number
		{
			return getRect(this).height;
		}
		
		override internal final function refreshScale():void
		{
			super.refreshScale();
			
			for each (var child:HEDisplayObject in this._children)
			{
				child.refreshScale();
			}
		}
		
		override internal final function refreshAlpha():void
		{
			super.refreshAlpha();
			
			for each (var child:HEDisplayObject in this._children)
			{
				child.refreshAlpha();
			}
		}
		
		override public function getRect(targetCoordinateSpace:HEDisplayObject = null):Rectangle
		{
			var rect:Rectangle = super.getRect(targetCoordinateSpace);
			
			for each (var child:HEDisplayObject in _children)
			{
				var childRect:Rectangle = child.getRect(targetCoordinateSpace ? targetCoordinateSpace : this);
				
				rect = rect.union(childRect);
			}
			
			return rect ? rect : new Rectangle();
		}
		
		override public final function hitTestPoint(x:Number, y:Number, shapeFlag:Boolean = false):Boolean
		{
			if (shapeFlag)
			{
				for (var i:int = _children.length - 1; i >= 0; i--)
				{
					if (_children[i].hitTestPoint(x, y, shapeFlag))
					{
						return true;
					}
				}
			}
			
			return super.hitTestPoint(x, y, shapeFlag);
		}
		
		public final function get numChildren():int
		{
			return _children.length;
		}
		
		public final function addChild(child:HEDisplayObject):HEDisplayObject
		{
			return addChildAt(child, _children.length);
		}
		
		public final function addChildAt(child:HEDisplayObject, index:int):HEDisplayObject
		{
			var oldParent:HEDisplayObjectContainer = child.parent;
			
			if (oldParent)
			{
				var index:int = oldParent.getChildIndex(child);
				index != -1 && oldParent.removeChildAt(index);
			}
			
			_children.splice(index, 0, child);
			child.refreshParent(this);
			
			return child;
		}
		
		public final function setChildIndex(child:HEDisplayObject, index:int):void
		{
			var oldIndex:int = _children.indexOf(child);
			
			if (oldIndex != -1)
			{
				_children.splice(oldIndex, 1);
				_children.splice(index, 0, child);
			}
			else
			{
				throw new Error("Cannot set index for a HEDisplayObject which is not a child of the HEDisplayObjectContainer.");
			}
		}
		
		public final function getChildAt(index:int):HEDisplayObject
		{
			return _children[index];
		}
		
		public final function getChildIndex(child:HEDisplayObject):int
		{
			return _children.indexOf(child);
		}
		
		public final function removeChildAt(index:int):HEDisplayObject
		{
			var result:HEDisplayObject = _children[index];
			result.refreshParent(null);
			
			_children.splice(index, 1);
			
			return result;
		}
		
		public final function getObjectsUnderPoint(point:Point):Vector.<HEDisplayObject>
		{
			const shapeFlag:Boolean = true;
			
			var result:Vector.<HEDisplayObject> = new Vector.<HEDisplayObject>();
			
			if (hitTestPoint(point.x, point.y, shapeFlag))
			{
				result.push(this);
			}
			
			for (var i:int = 0; i < _children.length; i++)
			{
				if (_children[i] is HEDisplayObjectContainer)
				{
					result = result.concat(HEDisplayObjectContainer(_children[i]).getObjectsUnderPoint(point));
				}
				else if(_children[i].hitTestPoint(point.x, point.y, shapeFlag))
				{
					result.push(_children[i]);
				}
			}
			
			return result;
		}
	}
}